package org.lboot.flow.module.work;


import cn.hutool.core.lang.Validator;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Hibernate;
import org.lboot.flow.constant.FlowNodeTypeConst;
import org.lboot.flow.constant.FlowWorkStatusEnum;
import org.lboot.flow.model.FlowModel;
import org.lboot.flow.model.node.*;
import org.lboot.jpa.converter.JpaListObjectConverter;
import org.lboot.jpa.entity.BaseEntity;
import org.lboot.jpa.entity.DateAuditBaseEntity;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author kindear
 * 流程实例
 */
@Slf4j
@Getter
@Setter
@ToString
@RequiredArgsConstructor
@Entity
@Table(name = "flow_work")
@ApiModel(value = "流程实例")
public class FlowWork extends BaseEntity implements Serializable {
    /**
     * 可以使用 JPA 级联映射
     */
    @ApiModelProperty("流程名称")
    @Column(name = "flow_name")
    String flowName;

    @ApiModelProperty("流程定义编码")
    @Column(name = "flow_code")
    String flowCode;


    @Convert(converter = JpaListObjectConverter.class)
    @Column(name = "node_list",columnDefinition = "TEXT")
    List<BaseModel> nodeList;


    // 可以代理流程发起，发起人为被代理人ID
    @ApiModelProperty("流程发起者ID")
    @Column(name = "initiator")
    String initiator;

    @ApiModelProperty("当前节点ID")
    @Column(name = "current_node_id")
    String currentNodeId;

    @ApiModelProperty("当前节点类型")
    @Column(name = "current_node_type")
    String currentNodeType;

    @ApiModelProperty("下一节点ID")
    @Column(name = "next_node_id")
    String nextNodeId;
    /**
     * 流程参数， 全流程可访问
     */
    @ApiModelProperty(value = "流程参数",name = "")
    @Column(name = "flow_param",length = 5112)
    String flowParam;


    // @TODO 修改为 JPA 枚举类映射
    @ApiModelProperty(value = "流程实例状态",name = "")
    @Column(name = "flow_work_status")
    String flowWorkStatus;

    /**
     * status 为 0 禁止进行修改任何操作
     */
    @ApiModelProperty(value = "实例状态",notes = "1正常 0被挂起")
    @Column(name = "status")
    Integer status;

    /**
     * 关联的业务ID
     */
    @ApiModelProperty("业务ID")
    @Column(name = "business_id")
    String businessId;
    /**
     * 关联的业务名称
     */
    @ApiModelProperty("业务名称")
    @Column(name = "business_name")
    String businessName;
    /**
     * 业务类型
     */
    @ApiModelProperty("业务类型")
    @Column(name = "business_type")
    String businessType;

    @ApiModelProperty(value = "流程实例到期时间",notes = "")
    @Column(name = "expire_date")
    Date expireDate;

    /**
     * 即对应流程的父流程
     */
    @ApiModelProperty(value = "根流程ID")
    @Column(name = "root_flow_id")
    String rootFlowId;

    /**
     * 通过id获取节点
     * @param nodeId
     * @return
     * @TODO 新增节点，该部分必须修改
     */
    @SneakyThrows
    public BaseModel getNodeModel(String nodeId) {
        return FlowModel.getNodeModel(this.nodeList, nodeId);
    }

    @JsonIgnore
    public BaseModel getCurrentModel() {
        return getNodeModel(this.currentNodeId);
    }

    @JsonIgnore
    public BaseModel getNextModel(){
        return getNodeModel(this.nextNodeId);
    }

    /**
     * 获取开始节点模型
     * @return
     */
    @JsonIgnore
    public StartModel getStartModel() {

        StartModel model = (StartModel) getNodeModel("start");
        if (Validator.isEmpty(model.getEnableAll())){
            model.setEnableAll(true);
        }
        return model;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
        FlowWork flowWork = (FlowWork) o;
        return id != null && Objects.equals(id, flowWork.id);
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
}
